package pl.donajski.magisterka;

import static org.junit.Assert.fail;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Date;
import java.util.List;


public class App 
{
    public static boolean _debug = false;

	public static void main( String[] args )
    {
		PrintWriter  fis = null;
		try {
			try {
				fis = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(args[3]))));
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
				return;
			}
			
			fis.println(new Date());
			fis.println("Tabu list length:\t" + Integer.parseInt(args[4]));
			fis.println("Neighbour loops:\t" + Integer.parseInt(args[5]));
			fis.println("Main loops:\t" + Integer.parseInt(args[6]));
			
			for(int i = 0; i < Integer.parseInt(args[7]); ++i ) {
				FileTaskLoader flt = null;
				FileNodeLoader fl = null;
				FileProtectionLoader fpl = null;
				List<Task> tasks = null;
				List<Node> nodes = null;
				try {
					fl = new FileNodeLoader(args[0]);
					nodes = fl.load();
					flt = new FileTaskLoader(args[1], nodes);
					tasks = flt.load();
					fpl = new FileProtectionLoader(args[2], tasks);
					tasks.addAll(fpl.load());
					
					int procMax = 0;
					for(Node n : nodes) {
						procMax += n.getProcessingRateMax();
					}
					
					if(procMax < tasks.size()) {
						fis.println(-1);
						break;
					}
						
				} catch (Exception e) {
					e.printStackTrace();
					fail();
				}
				finally {
					if(fl != null)
						fl.close();
					if(flt != null)
						flt.close();
				}
				int res = Integer.MAX_VALUE;
				int flowC = 0, procC = 0;
				/*for(int j = 0 ; j < Integer.parseInt(args[8]); ++j) {
					State is = new RandomGenerator().getInitialState(tasks, nodes);
					TabuSearch ts = new TabuSearch(is, 
							new SubstitutionGenerator(is, Float.parseFloat(args[9])), 
							new SubstitutionRemovedNodeTabuList(Integer.parseInt(args[4])),
							Integer.parseInt(args[5]),
							Integer.parseInt(args[6]));
					int curr = ts.solve();
					if(curr < res) {
						res = curr;
					}
				}
				*/
				State is = null;
				
				if(args[8].equals("chary"))
					is = new CharyHeuristicGenerator().getInitialState(tasks, nodes);
				else if(args[8].equals("rand"))
					is = new RandomGenerator().getInitialState(tasks, nodes);
				else if(args[8].equals("greed"))
					is = new GreedyGenerator().getInitialState(tasks, nodes);
				
				ITabuList tl = null;
				if(args[10].equals("remove"))
					tl = new SubstitutionRemovedNodeTabuList(Integer.parseInt(args[4]));
				else if(args[10].equals("add"))
					tl = new SubstitutionAddedNodeTabuList(Integer.parseInt(args[4])); 
						
				fis.println(is.getCost());
				
				TabuSearch ts = new TabuSearch(is, 
						new SubstitutionGenerator(is, Float.parseFloat(args[9])), 
						tl,
						Integer.parseInt(args[5]),
						Integer.parseInt(args[6]),
						Integer.parseInt(args[11]));
				
				int curr = ts.solve();
				if(curr < res) {
					res = curr;
				}
				
				fis.println(res);
			}
		} catch (Exception e) {
			e.printStackTrace();
			fis.println(-2);
		}
		finally {
			fis.close();
		}
    }
}
